﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
using VistaDB.Provider;

namespace GDA.Provider.VistaDB
{
    public class VistaDBProvider : GDA.Provider.Provider
    {
        public VistaDBProvider()
            : base("VistaDBProvider", "VistaDB.NET20.dll", "VistaDB.Provider.VistaDBConnection", "VistaDB.Provider.VistaDBDataAdapter", "VistaDB.Provider.VistaDBCommand", "VistaDB.Provider.VistaDBParameter", "@", true, "")
        {
            base.ExecuteCommandsOneAtATime = false;
            Uri uri = new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase);
            base.providerAssembly = Assembly.LoadFrom((uri.IsFile ? Path.GetDirectoryName(uri.LocalPath) : null) + @"\VistaDB.NET20.dll");
        }

        public override string QuoteExpression(string word)
        {
            return (" " + word + " ");
        }

        public override string SQLCommandLimit(List<Mapper> mapping, string sqlQuery, int startRecord, int size)
        {
               string[] strArray = null;
            string[] strArray2 = null;
            if (sqlQuery.IndexOf("ORDER BY", 0, StringComparison.OrdinalIgnoreCase) < 0)
            {
                if (mapping == null)
                {
                    throw new GDAException("Mapping not found");
                }
                Mapper mapper = mapping.Find(delegate (Mapper m) {
                    if (m.ParameterType != PersistenceParameterType.IdentityKey)
                    {
                        return m.ParameterType == PersistenceParameterType.Key;
                    }
                    return true;
                });
                if (mapper == null)
                {
                    mapper = mapping[0];
                }
                sqlQuery = sqlQuery + " ORDER BY " + this.QuoteExpression(mapper.Name);
            }
            int num = sqlQuery.IndexOf("ORDER BY", 0, StringComparison.OrdinalIgnoreCase);
            if (num >= 0)
            {
                strArray = sqlQuery.Substring(num + "ORDER BY".Length, sqlQuery.Length - (num + "ORDER BY".Length)).Split(new char[] { ',' });
                strArray2 = new string[strArray.Length];
                for (int i = 0; i < strArray.Length; i++)
                {
                    int length = strArray[i].IndexOf(" DESC", 0, StringComparison.OrdinalIgnoreCase);
                    if (length >= 0)
                    {
                        strArray2[i] = "DESC";
                        strArray[i] = strArray[i].Substring(0, length).Trim();
                    }
                    else
                    {
                        strArray2[i] = "ASC";
                        length = strArray[i].IndexOf(" ASC", 0, StringComparison.OrdinalIgnoreCase);
                        if (length >= 0)
                        {
                            strArray[i] = strArray[i].Substring(0, length).Trim();
                        }
                        else
                        {
                            strArray[i] = strArray[i].Trim();
                        }
                    }
                }
            }
            int num4 = sqlQuery.IndexOf("SELECT", 0, StringComparison.OrdinalIgnoreCase);
            int num7 = startRecord + size;
            sqlQuery = string.Format("SELECT TOP {0}", num7.ToString()) + sqlQuery.Substring(num4 + "SELECT".Length);
            sqlQuery = string.Format("SELECT * FROM (SELECT TOP {0} * FROM ({1}) AS inner_tbl", size, sqlQuery);
            if (num >= 0)
            {
                sqlQuery = sqlQuery + " ORDER BY ";
                for (int j = 0; j < strArray.Length; j++)
                {
                    sqlQuery = sqlQuery + strArray[j] + " " + ((strArray2[j] == "ASC") ? "DESC" : "ASC");
                    if ((j + 1) != strArray.Length)
                    {
                        sqlQuery = sqlQuery + ", ";
                    }
                }
            }
            sqlQuery = sqlQuery + ") AS outer_tbl";
            if (num >= 0)
            {
                sqlQuery = sqlQuery + " ORDER BY ";
                for (int k = 0; k < strArray.Length; k++)
                {
                    sqlQuery = sqlQuery + strArray[k] + " " + strArray2[k];
                    if ((k + 1) != strArray.Length)
                    {
                        sqlQuery = sqlQuery + ", ";
                    }
                }
            }
            return sqlQuery;
        }

        public override char QuoteCharacter
        {
            get
            {
                return ' ';
            }
        }

        public override string QuoteExpressionBegin
        {
            get
            {
                return " ";
            }
        }

        public override string QuoteExpressionEnd
        {
            get
            {
                return " ";
            }
        }

        public override string SqlQueryReturnIdentity
        {
            get
            {
                return "SELECT @@IDENTITY";
            }
        }

        public override bool SupportSQLCommandLimit
        {
            get
            {
                return true;
            }
        }
    }
}
